﻿using Admin.Application;
using Admin.Application.DynamicApi.System;
using Admin.Application.DynamicApi.System.Menu;
using Framework.Core;
using Framework.WebApi.Authentication;
using Framework.WebApi.Authorization;
using Framework.WebApi.Options;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;

namespace Admin.Authorization
{
	public class JwtHandler : AppAuthorizeHandler
	{
		private static readonly SysMenuService sysMenuService = App.GetRequiredService<SysMenuService>();

		/// <summary>
		/// 自动刷新Token
		/// </summary>
		/// <param name="context"></param>
		/// <param name="httpContext"></param>
		/// <returns></returns>
		public override async Task HandleAsync(AuthorizationHandlerContext context)
		{
			JWTSettingsOptions JwtSettings = App.GetConfig<JWTSettingsOptions>("JwtSettings");


			//var tokenExpire = 30;
			//var refreshTokenExpire = 30;
			if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext(), JwtSettings.ExpiredTime, (int)JwtSettings.RefreshTokenExpiredTime))
			{
				await AuthorizeHandleAsync(context);
			}
			else
			{
				context.Fail(); // 授权失败
				var currentHttpContext = context.GetCurrentHttpContext();
				if (currentHttpContext == null) return;
			}
		}

		///// <summary>
		///// 策略验证管道
		///// </summary>
		///// <param name="context"></param>
		///// <param name="httpContext"></param>
		///// <param name="requirement"></param>
		///// <returns></returns>
		//public override async Task<bool> PolicyPipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext, IAuthorizationRequirement requirement)
		//{
		//	return await Task.FromResult(true);
		//}

		public override async Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
		{
			// 已自动验证 Jwt Token 有效性
			return await CheckAuthorizeAsync(httpContext);
		}

		/// <summary>
		/// 权限校验核心逻辑
		/// </summary>
		/// <param name="httpContext"></param>
		/// <returns></returns>
		private static async Task<bool> CheckAuthorizeAsync(DefaultHttpContext httpContext)
		{
			if (App.User.FindFirst(ClaimConst.Account)?.Value == "superadmin") return true;

			// 路由名称
			var routeName = httpContext.Request.Path.StartsWithSegments("/api")
				? httpContext.Request.Path.Value![5..].Replace("/", ":")
				: httpContext.Request.Path.Value![1..].Replace("/", ":");

			// 获取用户拥有按钮权限集合
			var ownBtnPermList = await sysMenuService.GetOwnBtnPermList();
			if (ownBtnPermList.Exists(u => routeName.Equals(u, StringComparison.CurrentCultureIgnoreCase)))
				return true;

			// 获取系统所有按钮权限集合
			var allBtnPermList = await sysMenuService.GetAllBtnPermList();
			return allBtnPermList.TrueForAll(u => !routeName.Equals(u, StringComparison.CurrentCultureIgnoreCase));
		}
	}
}
